/*************************************************************************
 *                                                                       *
 * This file is part of the FreeMAPs distribution.  For full copyright   *
 * information, see COPYRIGHT and COPYING.LESSER.                        *
 *                                                                       *
 * Author:           sqbang                                              *
 * Email:            sqbang@ustc.edu                                     *
 * Date:             2013.11.21                                          *
 *                                                                       *
 *************************************************************************/

#ifndef FreeMAPs_include_COMMON_info_UnstructuredMeshInfo_h
#define FreeMAPs_include_COMMON_info_UnstructuredMeshInfo_h

#include "FreeMAPsConfig.h"

//COMMON headers
#include "COMMON/base/StateIndicator.h"
//#include "COMMON/enum/ChangeElemsOrderType.h"
#include "COMMON/enum/GeomTransferOperator.h"
//#include "COMMON/enum/ElemType.h"
//#include "COMMON/tbox/Point.h"
//#include "COMMON/mesh/Elem.h"
#include "COMMON/enum/MeshFileFormat.h"


namespace FreeMAPs
{

//forward declarations
class MeshReader;
//class MeshGeneratorStrategy;
//class MeshGroup;

class UnstructuredMeshInfo : public StateIndicator
{
public:

    explicit
    UnstructuredMeshInfo(
        const std::string& parent_name,
        const std::string& object_name);

    ~UnstructuredMeshInfo();

public:
    inline MeshReader*
    get_mesh_reader() const;

    inline bool
    build_mesh_from_file() const;
    
//    inline const MeshGeneratorStrategy*
//    get_mesh_generator() const;

//    inline bool
//    use_parallel_mesh() const;

//    inline bool
//    change_all_elems_to_triangle() const;

//    inline ChangeElemsOrderType
//    change_elems_order() const;

    //inline const std::vector<GeomTransferOperator>&
   // mesh_modification_order() const;
#if 0
    inline const Point&
    get_mesh_translation() const;

    inline const Point&
    get_mesh_rotation() const;

    inline const Point&
    get_mesh_scale() const;
#endif
    inline void
    set_mesh_translation(const double x = 0.,
                         const double y = 0.,
                         const double z = 0.);

    inline void
    set_mesh_rotation(const double x = 0.,
                      const double y = 0.,
                      const double z = 0.);

    inline void
    set_mesh_scale(const double x = 0.,
                   const double y = 0.,
                   const double z = 0.);

//    inline bool
//    remove_duplicate_nodes() const;

//    inline void
//    set_remove_duplicate_nodes_flag(
//        const bool flag);

//    inline bool
//    remove_duplicate_nodes_using_relative_tolerance() const;

//    inline double
//    remove_duplicate_nodes_tolerance() const;



public:

    void
    clear();

    void
    set_mesh_file_format(
            const MeshFileFormat mesh_file_format);

    void
    set_mesh_file_location(
            const std::string mesh_file_location);

    const std::string
    get_mesh_file_location() const;

    void
    get_from_input (
        const InputDatabase* db);

    friend std::ostream&
    operator << (
        std::ostream& os,
        const UnstructuredMeshInfo& rhs);

    bool
    check_all_info_db(const InputDatabase* db);



private:

    typedef StateIndicator Parent;

    /*
     * a mesh is build by reading information from a file or
     * from commands.
     */
    bool d_build_mesh_from_file;

    /*
     * if d_build_mesh_using_commands is true,
     * this used to build a mesh of quad type(include cubic type.)
     */
//    MeshGeneratorStrategy* d_mesh_generator;
    MeshReader* d_mesh_reader;

    /*
     * for libMesh package, parallel and serial mesh are supported.
     * the parallel mesh will save memory while serial mesh may be more robust.
     */
//    bool d_use_parallel_mesh;

    /*
     * Worked in 2D problem
     */
//    bool d_change_all_elems_to_triangle;

    /*
     * this is used in FEM simulation.
     */
//    ChangeElemsOrderType d_change_elems_order;

    /*
     * when modificate mesh, three method are supported:
     * translate, rotate, scale.
     * using this parameter to tell the order.
     * usually "translate->rotate->scale" is a recommend order.
     */
    //std::vector<GeomTransferOperator> d_mesh_modification_order;
    //Point d_mesh_translation;
    //Point d_mesh_rotation;
    //Point d_mesh_scale;

    /*
     * if duplicate nodes exists, remove it.
     */
//    bool d_remove_duplicate_nodes;
//    bool d_remove_duplicate_nodes_using_relative_tolerance;
//    double d_remove_duplicate_nodes_tolerance;
};

}

#include "COMMON/info/UnstructuredMeshInfo.inl"

#endif
